Day21 結尾留了一句話:「今天做的事情,範圍刻意收得很窄——沒有在這張圖上找核心樞紐、找斷點,那些分析邏輯今天完全沒碰。」今天要把這句話兌現:拿 Day21 匯出的
brain graph --json,動手讀出誰是樞紐、誰是斷點。
Day21 給的是原始資料——一份 nodes/edges 的 JSON,它本身不會主動告訴你任何事。今天要做的不是寫新程式,而是定義兩個判讀角度,直接在 Day21 demo vault 的既有輸出上手動算一次:樞紐(hub),回答「哪篇筆記是全庫最核心的節點」;斷點(breakpoint),回答「哪篇筆記一旦消失,其他筆記會不會因此互相失聯」。跟 Day20、Day21 一樣,今天不寫 obsidian-agent-brain 的任何程式碼,也不改動 Day21 已經定案的 brain graph/--json 輸出格式——這兩個判讀方法完全建立在既有 JSON 之上,用人工計算示範一次。
樞紐分數的定義很直接:一個節點的樞紐分數,等於它的 id 在 edges 陣列裡當 source 出現的次數,加上當 target 出現的次數。不分方向、雙向都算——因為無論是「被很多筆記引用」還是「引用很多其他筆記」,都代表這篇筆記在知識網格裡的活躍程度高,值得被當成核心樞紐特別維護。
這裡刻意不拆成 in-degree、out-degree 兩套排名。分開統計對讀者理解沒有額外幫助,也沒有下游需求要用到方向區分,所以維持一個分數、一個排名就好。
對 Day21 用的 demo vault 執行 brain graph --json,拿到跟 Day21 一致的 14 個節點、14 條邊:
{
"nodes": [
{"id": "20260815-093000", "label": "Cobra CLI 框架"},
{"id": "20260819-220325", "label": "Cobra flag 綁定筆記"},
{"id": "20260819-220757", "label": "Cobra 子指令樹筆記"},
{"id": "20260819-223000", "label": "選用 Cobra 作為 CLI 框架"},
{"id": "20260820-090000", "label": "Graphify 匯出格式規劃"},
{"id": "20260820-090100", "label": "Graphify 資料模型與 brain-cli 索引對應關係"},
{"id": "20260815-090000", "label": "PARA 筆記法"},
{"id": "20260820-090200", "label": "Obsidian Wikilink 語法備忘"}
// ...其餘 6 篇孤立筆記
],
"edges": [
{"source": "20260820-090000", "target": "20260820-090100"},
{"source": "20260815-093000", "target": "20260819-220325"},
{"source": "20260815-093000", "target": "20260819-220757"},
{"source": "20260815-093000", "target": "20260819-223000"},
{"source": "20260820-090100", "target": "20260820-090000"},
{"source": "20260819-220325", "target": "20260815-093000"},
{"source": "20260819-220325", "target": "20260819-220757"},
{"source": "20260819-220325", "target": "20260819-223000"},
{"source": "20260819-220757", "target": "20260815-093000"},
{"source": "20260819-220757", "target": "20260819-220325"},
{"source": "20260819-220757", "target": "20260819-223000"},
{"source": "20260819-223000", "target": "20260815-093000"},
{"source": "20260819-223000", "target": "20260819-220325"},
{"source": "20260819-223000", "target": "20260819-220757"}
],
"nodeCount": 14,
"edgeCount": 14
}
逐條邊統計每個節點當 source/target 的出現次數,加總得出樞紐分數:
| 節點(label) | 當 source | 當 target | 樞紐分數 |
|---|---|---|---|
| Cobra CLI 框架 | 3 | 3 | 6 |
| Cobra flag 綁定筆記 | 3 | 3 | 6 |
| Cobra 子指令樹筆記 | 3 | 3 | 6 |
| 選用 Cobra 作為 CLI 框架 | 3 | 3 | 6 |
| Graphify 匯出格式規劃 | 1 | 1 | 2 |
| Graphify 資料模型與 brain-cli 索引對應關係 | 1 | 1 | 2 |
| 其餘 8 篇孤立筆記 | 0 | 0 | 0 |
先做交叉核對:所有節點的樞紐分數加總 = 6×4 + 2×2 = 28,正好等於 edgeCount(14)的兩倍——因為每一條邊會同時貢獻給兩端節點各一次,這個等式是人工計算有沒有算錯的檢查方式,對上了。
排名結果也跟筆記內容對得上:「Cobra CLI 框架」「Cobra flag 綁定筆記」「Cobra 子指令樹筆記」「選用 Cobra 作為 CLI 框架」這四篇筆記彼此互相引用(讀完某一篇 Cobra 筆記的人,很自然會想連去看其他三篇),樞紐分數並列第一,是這座 demo vault 目前最需要小心維護的核心筆記——如果其中一篇被誤刪或改得語意走偏,會直接影響到另外三篇的連結完整性。「Graphify 匯出格式規劃」跟「Graphify 資料模型與 brain-cli 索引對應關係」只是單純互相連結的一對,分數 2,比 Cobra 群組低很多;其餘 8 篇孤立筆記維持 Day21 就記錄過的狀態,分數 0。
斷點借用圖論的**關節點(articulation point)**概念:先把每條 {source, target} 邊當成一條無向連線(忽略方向、忽略重複),建構無向圖;如果移除某個節點(連同它相連的所有邊)後,圖被拆成多個彼此不再相連的子圖,這個節點就是斷點。
為什麼判斷斷點時要放棄方向性?因為斷點要回答的是「這篇筆記消失後,其他筆記還連不連得到」,這是一個純粹的可達性問題,跟連結原本的方向無關——就算 A 連到 B 是單向的,一旦 B 真的消失,A 原本能經由 B 連到 C 的路徑一樣會斷掉,不會因為那條邊「本來是有向的」就有差別。這跟 Day20 強調的「雙向連結底層仍是兩條獨立有向邊、不能直接當成無向邊」並不衝突:Day20 談的是資料模型本身要不要合併方向,答案是不要;今天談的是在做「連通性分析」這一個特定判讀角度時,暫時忽略方向只是分析手法的選擇,圖的底層資料——Day21 的 GraphEdge{Source,Target}——完全沒有被改動。
把 demo vault 的 14 條邊去掉方向、去掉重複,實際上只剩下 7 條無向連線,可以分成幾個連通子圖:
也就是說,這座 demo vault 目前規模小、連結也集中在互相高度冗餘的小圈子裡,找不到一個「移除後真的會讓知識網格斷成幾塊」的節點。這裡老實承認這一點,改用一張額外繪製的小型示意圖,示範斷點判斷邏輯——下面這張圖是補充示意圖,不是 demo vault 的真實資料:
[Go 語言基礎筆記] — [Cobra CLI 框架筆記] — [brain scan 指令設計] — [brain health 檢查邏輯] — [brain graph 匯出格式]
這是一條鏈狀結構,5 個節點、4 條邊。逐一嘗試移除中間三個節點:
{Go 語言基礎筆記} 跟 {brain scan 指令設計, brain health 檢查邏輯, brain graph 匯出格式} 兩個各自連通、但彼此不再相連的子圖——是斷點。{Go 語言基礎筆記, Cobra CLI 框架筆記} 跟 {brain health 檢查邏輯, brain graph 匯出格式} 兩個子圖——也是斷點。{Go 語言基礎筆記, Cobra CLI 框架筆記, brain scan 指令設計} 跟 {brain graph 匯出格式} 兩個子圖——同樣是斷點。而兩端的「Go 語言基礎筆記」跟「brain graph 匯出格式」移除後,剩下的節點仍然是一條連續的鏈,沒有分裂——這兩個是葉節點,不是斷點。這張鏈狀示意圖剛好示範了斷點的核心直覺:斷點通常出現在「連接兩個群組的唯一橋樑」上,而不是出現在互相高度冗餘連結、繞得到彼此的密集群組裡——這正好呼應了 demo vault 裡 Cobra 群組因為互相兩兩連結而沒有斷點的原因。
樞紐跟斷點是同一份圖資料的兩個判讀角度,但指向的風險完全不同:樞紐分數高,代表這篇筆記很重要、被大量依賴,要小心維護內容品質;是斷點,代表這篇筆記若消失或被搬移,其他筆記會因此互相失聯,即使那些筆記各自的樞紐分數都不高。一篇筆記完全可能樞紐分數不高、卻是斷點——就像上面示意圖裡鏈狀中間的三個節點,每個只連到左右各一個鄰居,樞紐分數只有 2,但少了任何一個都會讓整條鏈斷成兩半。
今天在 Day21 匯出的圖資料上,定義了樞紐(不分方向的 degree 總和)跟斷點(暫時忽略方向後的關節點)兩套判讀方法,並在 demo vault 的真實資料上算出一次樞紐排名,也老實記錄了這座 demo vault 目前規模太小、連結又集中在冗餘群組裡,找不到有代表性的斷點,因此改用一張額外的鏈狀示意圖示範判斷邏輯。今天完全沒有新增任何 brain-cli 程式碼——這套判讀方法要不要、什麼時候自動化成指令,留給未來真正需要的時候再開一個新的 change 決定。
👉 明天 Day23,Stage 4 要從「看得懂圖」轉向「回答得出問題」——結合 Claude Code 跟 brain-cli,做一次混合檢索問答,讓知識庫不只能被畫成圖,還能被直接問問題。我們明天見!